<template>
  <div class="mb-flow-next-step" v-if="!isFinishedTask">
<!--     <van-cell :title="curnodeLabel" :value="curNode.documentation" v-if="curNode.documentation" title-class="van-field__label"/> -->
    <van-cell 
      :title="nodeLabel" 
      is-link 
      :value="node_display || placeholder" 
      :required="required" 
      :value-class="valueClass" 
      @click="nodeClick"
      title-class="van-field__label"
      v-if="showNextNode"
      />
    <van-cell :title="nodeDesc" :value="documentation" v-if="showNextNode && documentation" title-class="van-field__label"/>
    <van-cell 
      :title="assigneesLabel" 
      is-link 
      :value="assignees_display || placeholder" 
      :required="required" 
      :value-class="assigneeClass" 
      @click="assigneesClick"
      title-class="van-field__label"
      v-if="!isEndNode && showNextAssignees"/>
    <van-popup 
      v-model="nodePopup" 
      position="bottom"
    >
      <van-picker
        show-toolbar
        :columns="nodeList"
        value-key="nodeName"
        :default-index="nodeIdIndex"
        @cancel="nodePopup = false"
        @change="nodeChange"
        @confirm="nodeConfirm"
      />
    </van-popup>
    <van-popup 
      v-model="assigneesPopup" 
      position="bottom"
    >
      <div class="van-hairline--top-bottom van-picker__toolbar">
        <button type="button" class="van-picker__cancel" @click="assigneesCancel">取消</button>
        <button type="button" class="van-picker__confirm" @click="assigneesConfirm">确认</button>
      </div>
      <template v-if="multiple">
        <van-checkbox-group v-model="assigneesChecked" class="checkbox-group-container">
          <van-cell-group>
            <van-cell
              v-for="(item, index) in assigneesList"
              clickable
              :key="index"
              @click="toggle(index)"
            >
              <van-checkbox
                :name="item.userId"
                ref="checkboxes"
                shape="square"
                style="min-height:24px"
              >
                {{item.userName}}
              </van-checkbox>
            </van-cell>
          </van-cell-group>
        </van-checkbox-group>
      </template>
      <template v-else>
        <van-radio-group v-model="assigneesChecked" class="checkbox-group-container">
          <van-cell-group>
            <van-cell 
              v-for="(item, index) in assigneesList"
              :key="index"
              clickable 
              @click="assigneesChecked === item.userId">
              <van-radio slot="right-icon" :name="item.userId">{{item.userName}}</van-radio>
            </van-cell>
          </van-cell-group>
        </van-radio-group>
      </template>
    </van-popup>
    <tg-tree
      v-if="canCustom && defaultCustom" 
      v-model="customAssigneesPopup" 
      :key-id="assignees"
      :key-name="assignees_display"
      :options="treeOptions"
      :search-options="treeSearchOptions"
      :parent-selectable="false" 
      :is-view="false" 
      :is-async="true"
      :multiple="multiple"
      hasSearch
      @on-search="$_loadtreeSearch"
      @selector-click="$_loadTreeOptions"
      @selected-click="$_getNextAssigneesSelected">
    </tg-tree>
  </div>
</template>
<script>
import { serialize } from 'utils'
import { request } from 'utils/http'
const NEXT_NODE_URL = "/sys/emapflow/tasks/getNextNodesByTask.do",
      NEXT_ASSIGNEES_URL = "/sys/emapflow/definition/getAssigneesInBpmnByNode.do",
      USERTASK_TOOLBAR_URL = "/sys/emapflow/definition/queryUserTaskToolbar.do",
      USERS_URL = "/sys/emapflow/usergroup/getUsers.do";
      // CUR_NODE_URL = "/sys/emapflow/tasks/getCurrentNodesByTask.do";
export default {
  name: 'mb-flow-next-step',
  data() {
    return {
      // curNode: {},
      // curnodeLabel: '当前节点描述',
      nodeLabel: "下一步",
      required: true,
      nextNode: '',
      nodeIdIndex: 0,
      node_display: '',
      nodeList: [],
      placeholder: "请选择",
      nodePopup: false,
      isEndNode: false, // 标识当前节点是否为结束节点
      nodeDesc: ' 下一步说明',
      documentation: '',
      assigneesLabel: '下一步办理人',
      assignees: [],
      assigneesChecked: null, // [Array|String]
      assignees_display: null,
      assigneesList: [],
      assigneesPopup: false,
      hasMultiInstUsers: false, // 用来标识 multiInstUsers
      isFinishedTask: true, // 标识流程业务是否为已办结
      customAssigneesPopup: false,
      treeOptions: [],
      canCustom: false, // 标识是否使用自定义选人
      treeSearchOptions: []
    }
  },
  props: {
    value: Object,
    defId: String,
    defKey: String,
    taskId: String,
    showNextNode: {
      type: Boolean,
      default: true
    },
    showNextAssignees: {
      type: Boolean,
      default: true
    },
    oneLegKicking: Boolean,
    multiple: { // 自定义选人模式开启时，是否开启多选
      type: Boolean,
      default: true
    },
    defaultCustom: { // 无处理时，是否开启自定义选人模式
      type: Boolean,
      default: true
    },
    submitformdata: Object
  },
  computed: {
    valueClass() {
      return this.nextNode != null && this.nextNode != '' ? 'selected' : ''
    },
    assigneeClass() {
      return this.assignees.length > 0 && this.assignees_display != '' ? 'selected' : ''
    },
    nextstepObj() {
      return {
        nextNodeId: this.nextNode,
        nextAssignees: this.assignees.join(',')
      }
    }
  },
  mounted() {
    // 如果下一步节点，办理人都不存在，则停止所有请求
    if(!(this.showNextNode || this.showNextAssignees)) return;
    // taskId为 空字符串，标识当前为启动状态，根据这一特点，可以确定不是最后一个节点；如果[isFinishedTask = true],隐藏下一步组件
    const _this = this;
    if(this.taskId) {
      request(USERTASK_TOOLBAR_URL, {
        query: {
          taskId: this.taskId
        }
      }).then(function(res) {
        if(res && !res.isFinishedTask) {
          _this.isFinishedTask = false;
          _this.getNextNodes();
        }
      });
    }else{
      this.isFinishedTask = false;
      this.getNextNodes();
    }
    // 获取当前节点的信息
    // request(CUR_NODE_URL, {
    //   query: {
    //     taskId: this.taskId,
    //     defKey: this.defKey
    //   }
    // }).then(function(res) {
    //   if(res && res.currentNodes) {
    //     _this.curNode = res.currentNodes
    //   }  
    // });
  },
  methods: {
    nodeClick() {
      this.nodePopup = true;
    },
    assigneesClick() {
      if(!this.nextNode) {
        this.$toast("请先选择下一步节点")
        return
      }
      this.assigneesChecked = this.multiple ? Object.assign([], this.assignees) : this.assignees[0];
      if(this.assigneesList.length) {
        this.assigneesPopup = true;
      }else{
        if(this.defaultCustom) {
          this.customAssigneesPopup = true;
          this.treeOptions = [];
          this.$_loadTreeOptions();
        } else {
          this.$toast("无处理人可选")
        }
      }
    },
    nodeChange() {
      // ...
    },
    nodeConfirm(value, index) {
      if(this.nodeIdIndex !== index || (this.nodeIdIndex === index && !this.nextNode)) {
        this.canCustom = false;
        this.documentation = value.documentation||'';
        this.assignees = [];
        this.assigneesChecked = this.multiple ? [] : '';
        this.assigneesList = [];
        this.assignees_display = "";
        this.isEndNode = value.isEndNode === '1' ? true : false;
        this.getAssignees(value.nodeId);
      }
      this.nodeIdIndex = index;
      this.nextNode = value.nodeId;
      this.node_display = value.nodeName;
      this.nodePopup = false;
    },
    assigneesConfirm() {
      this.assignees = this.multiple ? Object.assign([], this.assigneesChecked) : [this.assigneesChecked];
      if(this.assignees.length) {
        let userNames = [];
        this.assigneesList.forEach(user => {
          if(this.assignees.indexOf(user.userId) > -1) userNames.push(user.userName)
        })
        this.assignees_display = userNames.join(',')
      }else{
        this.assignees_display = "";
      }
      this.assigneesPopup = false;
    },
    assigneesCancel() {
      this.assigneesPopup = false;
    },
    $_loadtreeSearch(keyword) {
      const _this = this;
      request(USERS_URL, {
        query: {
          appName: keyword
        }
      }).then((data)=> {
        _this.treeSearchOptions = data;
      })
    },
    $_loadTreeOptions(id) {
      const _this = this;
      request(USERS_URL, {
        query: {
          searchKey: id ||''
        }
      }).then(function(data) {
        _this.treeOptions = _this.treeDataTranslation(data);
      })
    },
    $_getNextAssigneesSelected(ids, label) {
      if(this.multiple){
        this.assignees = ids;
        this.assignees_display = label;
      } else {
        this.assignees = ids.id;
        this.assignees_display = ids.name;
      }
    },
    getNextNodes() {
      const _this = this;
      let formdata = this.submitformdata;
      if(!this.submitformdata && this.$parent && this.$parent.getFormData && typeof this.$parent.getFormData === "function") {
        formdata = this.$parent.getFormData();
      }
      let params = {
        taskId: this.taskId || null,
        defKey: this.defKey || null,
        formData: JSON.stringify(formdata)
      };
      request(NEXT_NODE_URL, {
        method: "POST",
        data: serialize({
          ...params
        }),
        headers: {
          "content-type": "application/x-www-form-urlencoded"
        }
      }).then(function(res) {
        if(res && res.nextNodes && Object.prototype.toString.call(res.nextNodes) === '[object Array]') {
          _this.nodeList = Object.assign([], res.nextNodes).map( item => {
            if(!item.nodeName) item.nodeName = item.isEndNode === "1" ? '结束' : item.nodeId;
            return item
          })
        }
        // 判断下一步节点是否唯一,不唯一 -->展示所有数据，可选；
        // 如果唯一 --> 判断该节点是否为结束（isEndNode ==='1'）：若是，则显示该节点并隐藏下一步办理人选择；若不是，则下一步办理人自动根据该节点的nodeId调用办理人接口
        if(_this.nodeList.length === 1) {
          _this.nextNode = _this.nodeList[0].nodeId;
          _this.node_display = _this.nodeList[0].nodeName;
          _this.nodeList[0].documentation;
          if(_this.nodeList[0].isEndNode === '1') {
            _this.isEndNode = true;
          }else{
            if(_this.showNextAssignees) {
              _this.isEndNode = false;
              _this.getAssignees(_this.nextNode);
            }
          }
        }else{
          // 如果nextNodes不唯一且【showNextNode = false】,那么将不显示下一步办理人，且利用isEndNode完成相应校验
          if(!_this.showNextNode){
            _this.isEndNode = true;
          }
        }
      });
    },
    getAssignees(nodeId) {
      const that = this;
      this.hasMultiInstUsers = false;
      let formdata = this.submitformdata;
      if(!this.submitformdata && this.$parent && this.$parent.getFormData && typeof this.$parent.getFormData === "function") {
        formdata = this.$parent.getFormData();
      }
      let params = {
        defId: this.defId || null,
        nodeId: nodeId,
        taskId: this.taskId || null,
        defKey: this.defKey || null,
        oneLegKicking: this.oneLegKicking,
        formData: JSON.stringify(formdata)
      };
      request(NEXT_ASSIGNEES_URL, {
        method: "POST",
        data: serialize({
          ...params
        }),
        headers: {
          "content-type": "application/x-www-form-urlencoded"
        }
      }).then(function(res) {
        if(res && res.items && !that.isEmptyObject(res.items)) {
          // 如果assignee存在数据，则将值赋给当前选人组件；如果不存在，则将candidates值合并并且去重赋值给选人组件
          let users = res.items.assignee;
          if(users && !that.isEmptyObject(users)) {
            that.assigneesList = [users];
            that.assignees = [users.userId];
            that.assignees_display = users.userName;
          }else{
            users = [];
            for(var key in res.items){
              if(key === "multiInstUsers") that.hasMultiInstUsers = true;
              if(key !== 'assignee'){
                users = users.concat(res["items"][key]);
              }
            }
            users = that.uniq(users);
            that.assigneesList = users;
            // 存在 multiInstUsers时，显示全部数据 
            if(that.hasMultiInstUsers) {
              that.assignees = [];
              let userNames = [];
              users.forEach(function(user){
                that.assignees.push(user.userId);
                userNames.push(user.userName);
              });
              that.assignees_display = userNames.join(",");
            }  
            // 判断是否只有一个人
            if(users.length === 1) {
              that.assignees = [users[0].userId];
              return
            } else {
              that.assignees = [];
              return
            }
          }
        } else {
          that.canCustom = true;
        }
      });
    },
    /**
     * 校验说明：根据下一步节点、下一步办理人的显示/不显示来确定是否校验
     */
    validate() {
      if(this.showNextNode && !this.nextNode) {
        this.$toast.fail('请选择下一步节点')
        return false;
      }
      if(!this.isEndNode && this.showNextAssignees && !this.assignees.join(',')) {
        this.$toast.fail('请选择下一步办理人')
        return false;
      }
      return true;
    },
    /**
     * 树数据统一化处理
     */
    treeDataTranslation: function(arr) {
      let result = [];
      result = arr.map(function(obj) {
        obj.isParent = obj.type === "group"?1:0;
        obj.pId = obj.superId ? obj.superId : '';
        return obj
      });
      return result;
    },
    /**
     * 联动表单，表单相关数据变更触发。当且仅流程设计器已配置下一步节点时，刷新下一步组件  (需求来自王志伟2019/4/24)
     */
    updateNextNodes() {
      if(this.showNextNode) {
        this.canCustom = false;
        this.nextNode = "";
        this.node_display = "";
        this.documentation = '';
        this.assignees = [];
        this.assigneesChecked = this.multiple ? [] : '';
        this.assigneesList = [];
        this.assignees_display = "";
        this.isEndNode = false;
        this.getNextNodes();
      }
    },
    toggle(index) {
      this.$refs.checkboxes[index].toggle();
    },
    isEmptyObject(obj) {
      for(var key in obj) {
        return false;
      }
      return true;
    },
    uniq(arr) {
      let tempId = [], tempObj = [];
      arr.forEach(function(obj) {
        if(tempId.indexOf(obj.userId) === -1) {
          tempId.push(obj.userId);
          tempObj.push(obj);
        }
      });
      return tempObj
    }
  }
}

</script>

<style scoped>
  .selected {
    color: #323233;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
  .checkbox-group-container {
    height: 266px;
    overflow: auto;
  }
</style>
